package com.ruoyi.iot.tcp;

import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit;

/**
 * TCP 客户端
 *
 * @author Howe
 * @since 2025-05-06
 */
@Slf4j
public class TcpClient {

    /**
     * 设备的 IP 地址
     */
    private String ip;
    /**
     * 设备的端口号
     */
    private int port;
    /**
     * 最大重试次数
     */
    private int maxRetries = 3;
    /**
     * 超时时间（毫秒）
     */
    private int timeout = 5000;

    /**
     * 构造 TCP 客户端
     *
     * @param ip   设备 IP 地址
     * @param port 设备端口号
     */
    public TcpClient(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    /**
     * 获取设备数据，带有重试机制和超时处理。
     *
     * @param command 采集命令
     * @return 设备返回的数据，失败返回 null
     */
    public String getDeviceData(String command) {
        int attempts = 0;

        // 重试机制
        while (attempts < maxRetries) {
            try (Socket socket = new Socket()) {
                // 设置连接超时
                socket.connect(new java.net.InetSocketAddress(ip, port), timeout);

                // 设置读取超时
                socket.setSoTimeout(timeout);

                // 获取输入输出流
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);

                // 发送采集命令给设备
                writer.println(command);

                // 读取设备返回的数据
                StringBuilder data = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    data.append(line);
                }

                // 成功获取数据，返回数据
                return data.toString();
            } catch (SocketTimeoutException e) {
                log.error("读取超时：设备无响应，重试次数：" + (attempts + 1));
            } catch (IOException e) {
                log.error("连接或读取设备数据时发生错误：" + e.getMessage());
            }

            // 如果未成功，等待一段时间再重试
            attempts++;
            if (attempts < maxRetries) {
                log.info("尝试重新连接设备，重试次数：" + attempts);
                try {
                    // 延迟2秒后重试
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException ie) {
                    log.error("重试过程中被中断：" + ie.getMessage());
                }
            }
        }

        // 如果重试次数用完，返回 null
        log.error("设备没有返回数据，重试已达最大次数：" + maxRetries);
        return null;
    }
}